package com.lanhe.admin.controller.identifier;

import com.lanhe.common.annotation.Log;
import com.lanhe.common.constant.Constants;
import com.lanhe.common.core.controller.BaseController;
import com.lanhe.common.core.domain.AjaxResult;
import com.lanhe.common.core.page.TableDataInfo;
import com.lanhe.common.enums.BusinessType;
import com.lanhe.common.utils.StringUtils;
import com.lanhe.common.utils.poi.ExcelUtil;
import com.lanhe.identifier.domain.*;
import com.lanhe.identifier.domain.dto.LhIdentifierBindDTO;
import com.lanhe.identifier.service.*;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * 识别码（绑定）(LhIdentifierBind)表控制层
 *
 * @author zhanggl
 * @since 2023-09-18 20:07:33
 */
@RestController
@RequestMapping("lhIdentifierBind")
public class LhIdentifierBindController extends BaseController {

    @Resource
    private ILhIdentifierBindService lhIdentifierBindService;

    @Resource
    private ILhIdentifierBindLogService lhIdentifierBindLogService;

    @Resource
    private ILhIdentifierService lhIdentifierService;

    @Resource
    private ILhUserService lhUserService;

    @Resource
    private ILhIdentifierUseLogService iLhIdentifierUseLogService;

    /**
     * 分页查询所有数据
     */
    @PreAuthorize("@ss.hasPermi('identifier:identifierBind:list')")
    @GetMapping("/list")
    public TableDataInfo list(LhIdentifierBind identifierBind) {
        startPage();
        List<LhIdentifierBind> list = lhIdentifierBindService.selectIdentifierBindList(identifierBind);
        return getDataTable(list);
    }

    /**
     * 根据编号获取详细信息
     */
    @PreAuthorize("@ss.hasPermi('identifier:identifierBind:query')")
    @GetMapping(value = {"/", "/{identifierBindId}"})
    public AjaxResult getInfo(@PathVariable(value = "identifierBindId") Long identifierBindId) {
        return success(lhIdentifierBindService.selectIdentifierBindById(identifierBindId));
    }

    /**
     * 绑定身份识别码
     */
    @PreAuthorize("@ss.hasPermi('identifier:identifierBind:add')")
    @Transactional
    @Log(title = "识别码绑定管理", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody List<LhIdentifierBindDTO> identifierBindDTO) {

        int numberTotal = 0;
        for (LhIdentifierBindDTO lhIdentifierBindDTO : identifierBindDTO) {
            // 检查是否选择了老师
            if (null == lhIdentifierBindDTO.getGroupId() || lhIdentifierBindDTO.getGroupId() <= 0
                || null == lhIdentifierBindDTO.getTeacherId() || lhIdentifierBindDTO.getTeacherId() <= 0) {
                return error("请选择所属老师");
            }

            // 检查学员名称是否为空
            for (LhIdentifierBindDTO.Items item : lhIdentifierBindDTO.getItem()) {
                if (StringUtils.isBlank(item.getStudent())) {
                    return error("请输入学员名称");
                }
            }

            // 检查有效期是否为空
            for (LhIdentifierBindDTO.Items item : lhIdentifierBindDTO.getItem()) {
                if (null == item.getDeadline() || item.getDeadline() <= 0) {
                    return error("请输入有效期限");
                }
            }

            // 计算总数
            numberTotal += lhIdentifierBindDTO.getItem().size();
        }
        if (numberTotal <= 0) {
            return error("需要提取的识别码数量有误");
        }

        List<LhIdentifier> lhIdentifiers = lhIdentifierService.extractByNumber(numberTotal);
        if (lhIdentifiers.size() < numberTotal) {
            return error("可提取的识别码数量不足，请先生成识别码");
        }

        int i = 0;
        for (LhIdentifierBindDTO lhIdentifierBindDTO : identifierBindDTO) {

            LhIdentifierBindLog lhIdentifierBindLog = new LhIdentifierBindLog();
            Integer number = lhIdentifierBindDTO.getItem().size();
            lhIdentifierBindLog.setGroupId(lhIdentifierBindDTO.getGroupId());
            lhIdentifierBindLog.setTeacherId(lhIdentifierBindDTO.getTeacherId());
            lhIdentifierBindLog.setNumber(number);
            lhIdentifierBindLog.setCreateBy(getUsername());
            lhIdentifierBindLogService.insertIdentifierBindLog(lhIdentifierBindLog);

            List<LhIdentifierBind> identifierBinds = new ArrayList<>();
            for (LhIdentifierBindDTO.Items item : lhIdentifierBindDTO.getItem()) {
                Date nowDate = new Date();
                LhIdentifierBind identifierBind = new LhIdentifierBind();
                identifierBind.setIdentifierBindLogId(lhIdentifierBindLog.getIdentifierBindLogId());
                identifierBind.setGroupId(lhIdentifierBindDTO.getGroupId());
                identifierBind.setTeacherId(lhIdentifierBindDTO.getTeacherId());
                identifierBind.setIdentifierId(lhIdentifiers.get(i).getIdentifierId());
                identifierBind.setIdentifier(lhIdentifiers.get(i).getIdentifier());
                identifierBind.setStudent(item.getStudent());
                identifierBind.setPlatform(item.getPlatform());
                identifierBind.setPaymentVoucher(item.getPaymentVoucher());
                identifierBind.setPrice(item.getPrice());
                identifierBind.setDeadline(item.getDeadline());
                identifierBind.setCreateBy(getUsername());
                identifierBind.setCreateTime(nowDate);
                identifierBinds.add(identifierBind);
                i++;
            }
            lhIdentifierBindService.insertIdentifierBind(identifierBinds);
        }

        // 修改已提取的状态
        Long[] identifierIds = lhIdentifiers.stream().map(LhIdentifier::getIdentifierId).toArray(Long[]::new);
        lhIdentifierService.updateExtractStatus(identifierIds);
        return success();
    }

    /**
     * 修改身份识别码
     */
    @PreAuthorize("@ss.hasPermi('identifier:identifierBind:edit')")
    @Log(title = "识别码绑定管理", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody LhIdentifierBind lhIdentifierBind) {
        if (ObjectUtils.isEmpty(lhIdentifierBind.getIdentifierBindId())
            || null == lhIdentifierBind.getIdentifierBindId()) {
            return error("主键ID不能为空");
        }
        lhIdentifierBind.setUpdateBy(getUsername());
        return toAjax(lhIdentifierBindService.updateLhIdentifierBind(lhIdentifierBind));
    }

    /**
     * 修改状态（开启关闭授权）
     */
    @PreAuthorize("@ss.hasPermi('identifier:identifierBind:empower')")
    @Log(title = "识别码绑定管理", businessType = BusinessType.UPDATE)
    @PutMapping("/empower")
    public AjaxResult empower(@RequestBody LhIdentifierBind lhIdentifierBind) {
        if (ObjectUtils.isEmpty(lhIdentifierBind.getIdentifierBindId())
            || null == lhIdentifierBind.getIdentifierBindId()) {
            return error("主键ID不能为空");
        }
        if (ObjectUtils.isEmpty(lhIdentifierBind.getStatus()) || null == lhIdentifierBind.getStatus()) {
            return error("状态值不能为空");
        }
        LhIdentifierBind resource =
            lhIdentifierBindService.selectIdentifierBindById(lhIdentifierBind.getIdentifierBindId());
        if (null == resource) {
            return error("未能查到该身份识别码");
        }
        if (!Constants.GeneralIntType.ONE.equals(Integer.valueOf(resource.getIsUse()))) {
            return error("该身份识别码尚未使用,不能进行该操作");
        }
        lhIdentifierBind.setUpdateBy(getUsername());
        return toAjax(lhIdentifierBindService.empower(lhIdentifierBind));
    }

    /**
     * 统计已使用、未使用
     */
    @GetMapping("/stat")
    public AjaxResult stat() {
        return success(lhIdentifierBindService.stat());
    }

    @Log(title = "身份识别码管理", businessType = BusinessType.EXPORT)
    @PreAuthorize("@ss.hasPermi('identifier:identifierBind:export')")
    @PostMapping("/export")
    public void export(HttpServletResponse response, LhIdentifierBind lhIdentifierBind) {
        List<LhIdentifierBind> list = lhIdentifierBindService.selectIdentifierBindList(lhIdentifierBind);
        ExcelUtil<LhIdentifierBind> util = new ExcelUtil<LhIdentifierBind>(LhIdentifierBind.class);
        util.exportExcel(response, list, "身份识别码数据");
    }

    /**
     * 使用身份识别码
     */
    @Transactional
    @GetMapping("/verify/{identifier}")
    public AjaxResult verify(@PathVariable(value = "identifier", required = false) String identifier) {
        if (StringUtils.isBlank(identifier)) {
            return error("激活码不能为空");
        }
        LhIdentifierBind lhIdentifierBind = lhIdentifierBindService.selectIdentifierBindByIdentifier(identifier);
        if (null == lhIdentifierBind) {
            return error("激活码不存在");
        }
        if (Constants.GeneralIntType.ONE.equals(Integer.valueOf(lhIdentifierBind.getStatus()))) {
            return error("激活码已被禁用");
        }
        if (Constants.GeneralIntType.ONE.equals(Integer.valueOf(lhIdentifierBind.getIsUse()))) {

            String dateTimeStr = String.valueOf(lhIdentifierBind.getUsageTime());
            SimpleDateFormat originalFormat = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy", Locale.US);
            Date date = null;
            try {
                date = originalFormat.parse(dateTimeStr);
            } catch (ParseException e) {
                throw new RuntimeException(e);
            }

            // 使用时间（毫秒）
            long timestampMillis = date.getTime();

            // 当前时间（毫秒）
            long currentTimestampMillis = System.currentTimeMillis();
            long phaseTime = currentTimestampMillis - (timestampMillis+lhIdentifierBind.getDeadline()* 24 * 60 * 60 * 1000L);
            if (phaseTime >= 0) {
                return error("激活码已过期");
            }
        }
        return success();
    }

    /**
     * 使用身份识别码
     */
    @Transactional
    @GetMapping("/use/{identifier}")
    public AjaxResult use(@PathVariable(value = "identifier", required = false) String identifier) {
        if (StringUtils.isBlank(identifier)) {
            return error("激活码不能为空");
        }
        LhIdentifierBind lhIdentifierBind = lhIdentifierBindService.selectIdentifierBindByIdentifier(identifier);
        if (null == lhIdentifierBind) {
            return error("激活码不存在");
        }
        if (Constants.GeneralIntType.ONE.equals(Integer.valueOf(lhIdentifierBind.getStatus()))) {
            return error("激活码已被禁用");
        }
        if (Constants.GeneralIntType.ONE.equals(Integer.valueOf(lhIdentifierBind.getIsUse()))) {

            String dateTimeStr = String.valueOf(lhIdentifierBind.getUsageTime());
            SimpleDateFormat originalFormat = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy", Locale.US);
            Date date = null;
            try {
                date = originalFormat.parse(dateTimeStr);
            } catch (ParseException e) {
                throw new RuntimeException(e);
            }

            // 使用时间（毫秒）
            long timestampMillis = date.getTime();

            // 当前时间（毫秒）
            long currentTimestampMillis = System.currentTimeMillis();
            long phaseTime = currentTimestampMillis - (timestampMillis+lhIdentifierBind.getDeadline()* 24 * 60 * 60 * 1000L);
            if (phaseTime >= 0) {
                return error("激活码已过期");
            }
        }

        if (null == lhUserService.selectUserByIdentifier(identifier)){
            LhUser user = new LhUser();
            user.setUserKey(identifier);
            lhUserService.insertUser(user);

            LhIdentifierUseLog log = new LhIdentifierUseLog();
            log.setUserId(user.getUserId());
            log.setIdentifierId(lhIdentifierBind.getIdentifierId());
            log.setIdentifier(lhIdentifierBind.getIdentifier());
            log.setPrice(lhIdentifierBind.getPrice());
            log.setDeadline(lhIdentifierBind.getDeadline());

            LocalDate currentDate = LocalDate.now();
            DateTimeFormatter formatterYear = DateTimeFormatter.ofPattern("yyyy");
            String formattedYear = currentDate.format(formatterYear);
            DateTimeFormatter formatterYearMonth = DateTimeFormatter.ofPattern("yyyyMM");
            String formattedYearMonth = currentDate.format(formatterYearMonth);
            DateTimeFormatter formatterYearMonthDay = DateTimeFormatter.ofPattern("yyyyMMdd");
            String formattedYearMonthDay = currentDate.format(formatterYearMonthDay);

            log.setYear(Integer.valueOf(formattedYear));
            log.setMonth(Integer.valueOf(formattedYearMonth));
            log.setDay(Integer.valueOf(formattedYearMonthDay));
            iLhIdentifierUseLogService.insertUseLog(log);
            lhIdentifierBindService.useIdentifierBindByIdentifier(identifier);
        }

        Map<String,String> map = new HashMap<>();
        map.put("identifier",lhIdentifierBind.getIdentifier());
        return success(map);
    }



    @Log(title = "身份识别码管理", businessType = BusinessType.UPDATE)
    @PreAuthorize("@ss.hasPermi('identifier:identifierBind:disable')")
    @GetMapping("/disable/{lhIdentifierBindId}")
    public AjaxResult disable(@PathVariable("lhIdentifierBindId") Long lhIdentifierBindId) {

        if (ObjectUtils.isEmpty(lhIdentifierBindId)) {
            return error("主键ID不能为空");
        }
        LhIdentifierBind lhIdentifierBind = lhIdentifierBindService.selectIdentifierBindById(lhIdentifierBindId);
        if (Constants.GeneralIntType.ZERO.equals(Integer.valueOf(lhIdentifierBind.getIsUse()))){
            return error("该身份识别码尚未激活，无法禁用");
        }
        LhIdentifierBind lh = new LhIdentifierBind();
        lh.setIdentifierBindId(lhIdentifierBindId);
        lh.setStatus("1");
        lh.setUpdateBy(getUsername());
        return toAjax(lhIdentifierBindService.updateLhIdentifierBind(lh));
    }

    @Log(title = "身份识别码管理", businessType = BusinessType.UPDATE)
    @PreAuthorize("@ss.hasPermi('identifier:identifierBind:open')")
    @GetMapping("/open/{lhIdentifierBindId}")
    public AjaxResult open(@PathVariable("lhIdentifierBindId") Long lhIdentifierBindId) {
        if (ObjectUtils.isEmpty(lhIdentifierBindId)) {
            return error("主键ID不能为空");
        }
        LhIdentifierBind lhIdentifierBind = new LhIdentifierBind();
        lhIdentifierBind.setIdentifierBindId(lhIdentifierBindId);
        lhIdentifierBind.setStatus("0");
        lhIdentifierBind.setUpdateBy(getUsername());
        return toAjax(lhIdentifierBindService.updateLhIdentifierBind(lhIdentifierBind));
    }
}
